//
//  ZCTool.m
//  Mooc
//
//  Created by ZhangCheng on 15/11/16.
//  Copyright © 2015年 ZhangCheng. All rights reserved.
//

#include <sys/param.h>
#include <sys/mount.h>


#import "ZCTool.h"

#import <CommonCrypto/CommonDigest.h>
#import "QN_GTM_Base64.h"

#include <ifaddrs.h>
#include <arpa/inet.h>
#include <net/if.h>
#define IOS_CELLULAR    @"pdp_ip0"
#define IOS_WIFI        @"en0"
//#define IOS_VPN       @"utun0"
#define IP_ADDR_IPv4    @"ipv4"
#define IP_ADDR_IPv6    @"ipv6"

@interface ZCTool(){
}

@end
@implementation ZCTool

+(NSString *)reviseString:(NSString *)str
{
    //直接传入精度丢失有问题的Double类型
    double conversionValue = [str doubleValue];
    NSString *doubleString = [NSString stringWithFormat:@"%lf", conversionValue];
    NSDecimalNumber *decNumber = [NSDecimalNumber decimalNumberWithString:doubleString];
    return [decNumber stringValue];
}

+(ZCTool *)sharedInstance{
    static ZCTool *zcTool;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        zcTool = [[ZCTool alloc]init];
    });
    return zcTool;
}

-(NSString *)base64ByZC:(NSString *)originString{
    NSData* bytes = [originString dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableString *mString = [[NSMutableString alloc]initWithString:[QN_GTM_Base64 stringByEncodingData:bytes]];
    NSInteger x = 1 + arc4random() % 9 ;
    NSString *chiString = @"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@#$%^&*()_+:<>";
    NSInteger i = arc4random() % chiString.length;
    NSString *chi = [chiString substringWithRange:NSMakeRange(i, 1)];
    [mString insertString:[NSString stringWithFormat:@"%@",@(x)] atIndex:mString.length-1];
    [mString insertString:chi atIndex:x];
    return [NSString stringWithString:mString];
}

- (NSString *)getIPAddress:(BOOL)preferIPv4
{
    NSArray *searchArray = preferIPv4 ?
    @[  IOS_WIFI @"/" IP_ADDR_IPv4, IOS_WIFI @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6 ] :
    @[  IOS_WIFI @"/" IP_ADDR_IPv6, IOS_WIFI @"/" IP_ADDR_IPv4, IOS_CELLULAR @"/" IP_ADDR_IPv6, IOS_CELLULAR @"/" IP_ADDR_IPv4 ] ;
    
    NSDictionary *addresses = [self getIPAddresses];
    NSLog(@"addresses: %@", addresses);
    
    __block NSString *address;
    [searchArray enumerateObjectsUsingBlock:^(NSString *key, NSUInteger idx, BOOL *stop)
     {
         address = addresses[key];
         if(address) *stop = YES;
     } ];
    return address ? address : @"0.0.0.0";
}
- (NSDictionary *)getIPAddresses
{
    NSMutableDictionary *addresses = [NSMutableDictionary dictionaryWithCapacity:8];
    
    // retrieve the current interfaces - returns 0 on success
    struct ifaddrs *interfaces;
    if(!getifaddrs(&interfaces)) {
        // Loop through linked list of interfaces
        struct ifaddrs *interface;
        for(interface=interfaces; interface; interface=interface->ifa_next) {
            if(!(interface->ifa_flags & IFF_UP) /* || (interface->ifa_flags & IFF_LOOPBACK) */ ) {
                continue; // deeply nested code harder to read
            }
            const struct sockaddr_in *addr = (const struct sockaddr_in*)interface->ifa_addr;
            char addrBuf[ MAX(INET_ADDRSTRLEN, INET6_ADDRSTRLEN) ];
            if(addr && (addr->sin_family==AF_INET || addr->sin_family==AF_INET6)) {
                NSString *name = [NSString stringWithUTF8String:interface->ifa_name];
                NSString *type;
                if(addr->sin_family == AF_INET) {
                    if(inet_ntop(AF_INET, &addr->sin_addr, addrBuf, INET_ADDRSTRLEN)) {
                        type = IP_ADDR_IPv4;
                    }
                } else {
                    const struct sockaddr_in6 *addr6 = (const struct sockaddr_in6*)interface->ifa_addr;
                    if(inet_ntop(AF_INET6, &addr6->sin6_addr, addrBuf, INET6_ADDRSTRLEN)) {
                        type = IP_ADDR_IPv6;
                    }
                }
                if(type) {
                    NSString *key = [NSString stringWithFormat:@"%@/%@", name, type];
                    addresses[key] = [NSString stringWithUTF8String:addrBuf];
                }
            }
        }
        // Free memory
        freeifaddrs(interfaces);
    }
    return [addresses count] ? addresses : nil;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        
        if (!([[NSUserDefaults standardUserDefaults]objectForKey:@"userInfo"] && [[[NSUserDefaults standardUserDefaults]objectForKey:@"userInfo"] isKindOfClass:[NSData class]])) {
            self.userInfo=nil;
        }else{
            self.userInfo = [NSKeyedUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults]objectForKey:@"userInfo"]];
        }
        if (!([[NSUserDefaults standardUserDefaults]objectForKey:@"tokenString"] && [[[NSUserDefaults standardUserDefaults]objectForKey:@"tokenString"] isKindOfClass:[NSString class]])) {
            self.tokenString=nil;
        }else{
            self.tokenString = [[NSUserDefaults standardUserDefaults]objectForKey:@"tokenString"];
        }
        
    }
    return self;
}

+ (CGFloat)localFileSpaceInMB{
//    unsigned long long space = 0;
//
//    NSFileManager* manager = [NSFileManager defaultManager];
//    
////    if ([manager fileExistsAtPath:PATH_CACHE_DIR]){
////        
////        space += [[manager attributesOfItemAtPath:PATH_CACHE_DIR error:nil] fileSize];
////    }
//    
//    if ([manager fileExistsAtPath:NSHomeDirectory()]){
//        
//        space += [[manager attributesOfItemAtPath:NSHomeDirectory() error:nil] fileSize];
//    }
   
    return [[ZCTool sharedInstance]folderSizeAtPath:NSHomeDirectory()];
}
- (CGFloat)folderSizeAtPath:(NSString *) folderPath
{
    NSFileManager * manager = [NSFileManager defaultManager];
    
    if (![manager fileExistsAtPath:folderPath])
    {
        return 0;
    }
    
    NSEnumerator * childFilesEnumerator = [[manager subpathsAtPath:folderPath] objectEnumerator];
    NSString * fileName;
    
    long long folderSize = 0;
    
    while ((fileName = [childFilesEnumerator nextObject]) != nil)
    {
        
        NSString * fileAbsolutePath = [folderPath stringByAppendingPathComponent:fileName];
        
        float singleFileSize = 0.0;
        if ([manager fileExistsAtPath:fileAbsolutePath])
        {
            singleFileSize = [[manager attributesOfItemAtPath:fileAbsolutePath error:nil] fileSize];
        }
        folderSize += singleFileSize;
        
    }
    return folderSize/1024.0f/1024.0f;
    
}

+ (CGFloat)freeDiskSpaceInMB{
    struct statfs buf;
    long long freespace = -1;
    if(statfs("/var", &buf) >= 0){
        freespace = (long long)(buf.f_bsize * buf.f_bfree);
    }
    return freespace/1024.0f/1024.0f;
}

-(void)login:(NSDictionary *)user{
    
    self.userInfo = [NSDictionary dictionaryWithDictionary:user];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:self.userInfo];
    [[NSUserDefaults standardUserDefaults]setObject:data forKey:@"userInfo"];
    [[NSUserDefaults standardUserDefaults]synchronize];
}

-(void)logout{
    if (self.tokenString!=nil) {
        [[NSUserDefaults standardUserDefaults]setObject:nil forKey:@"tokenString"];
        [[NSUserDefaults standardUserDefaults]synchronize];
        self.tokenString = nil;
    }
    if (self.userInfo!=nil) {
        self.userInfo = nil;
        [[NSUserDefaults standardUserDefaults]setObject:nil forKey:@"userInfo"];
        [[NSUserDefaults standardUserDefaults]synchronize];
    }
}


-(BOOL)isValidateUsername:(NSString *)username{
//    NSString *emailRegex = @"^[a-zA-Z0-9]+[a-zA-Z0-9_]*";
    NSString *emailRegex = @"^[a-zA-Z][a-zA-Z0-9_]*$";
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    
    return [emailTest evaluateWithObject:username];
}

- (BOOL)validateLearnNum:(NSString *)learnNum
{
    NSString *learnNumRegex = @"^[0-9]*$";
    NSPredicate *learnNumText = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",learnNumRegex];
   
    return [learnNumText evaluateWithObject:learnNum];
}

- (BOOL)validatePassword:(NSString *)password
{
    NSString *pwdRegex = @"^[^\u4e00-\u9fa5]{0,}$";
    NSPredicate *pwdText = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",pwdRegex];
    
    return [pwdText evaluateWithObject:password];
}

- (BOOL)validateMobile:(NSString *)mobileNum
{
    /**
     * 手机号码
     * 移动：134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
     * 联通：130,131,132,152,155,156,185,186
     * 电信：133,1349,153,180,189
     */
    NSString * MOBILE = @"^1(3[0-9]|5[0-35-9]|8[0-9]|7[5-8]|4[57])\\d{8}$";
    /**
     10         * 中国移动：China Mobile
     11         * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
     12         */
    NSString * CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$";
    /**
     15         * 中国联通：China Unicom
     16         * 130,131,132,152,155,156,185,186
     17         */
    NSString * CU = @"^1(3[0-2]|5[256]|8[56])\\d{8}$";
    /**
     20         * 中国电信：China Telecom
     21         * 133,1349,153,180,189
     22         */
    NSString * CT = @"^1((33|53|8[09])[0-9]|349)\\d{7}$";
    /**
     25         * 大陆地区固话及小灵通
     26         * 区号：010,020,021,022,023,024,025,027,028,029
     27         * 号码：七位或八位
     28         */
    // NSString * PHS = @"^0(10|2[0-5789]|\\d{3})\\d{7,8}$";
    
    NSPredicate *regextestmobile = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", MOBILE];
    NSPredicate *regextestcm = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CM];
    NSPredicate *regextestcu = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CU];
    NSPredicate *regextestct = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", CT];
    
    if (([regextestmobile evaluateWithObject:mobileNum] == YES)
        || ([regextestcm evaluateWithObject:mobileNum] == YES)
        || ([regextestct evaluateWithObject:mobileNum] == YES)
        || ([regextestcu evaluateWithObject:mobileNum] == YES))
    {
        return YES;
    }
    else
    {
        return NO;
    }
}

-(BOOL)isValidateEmail:(NSString *)email {
    
    NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
    
    NSPredicate *emailTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    
    return [emailTest evaluateWithObject:email];
    
}

-(BOOL)isLogin{
    return self.tokenString!=nil;
}

//-(NetworkStatus)GetCurrntNet
//{
//    Reachability *r = [Reachability reachabilityWithHostName:@"www.baidu.com"];
//    
//    return [r currentReachabilityStatus];
//    
//    
//}
- (NSString *)md5HexDigest:(NSString*)input
{
    // 需要MD5加密的字符
    const char *cStr = [input UTF8String];
    // 设置字符加密后存储的空间
    unsigned char digest[CC_MD5_DIGEST_LENGTH];
    
    // 参数三：编码的加密机制
    CC_MD5(cStr, (UInt32)strlen(cStr), digest);
    
    NSMutableString *result = [[NSMutableString alloc] initWithCapacity:16];
    
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i ++) {
        
        [result appendFormat:@"%02x",digest[i]];
        
    }
    
    result = (NSMutableString *)[result stringByAppendingString:@".mp3"];
    
    return result;
    
}
+ (NSString*) getUUIDString
{
    CFUUIDRef uuidObj = CFUUIDCreate(nil);
    NSString *uuidString = (__bridge_transfer NSString*)CFUUIDCreateString(nil, uuidObj);
    CFRelease(uuidObj);
    return uuidString;
}
-(NSString *)replaceOrAddQueryItem:(NSURLQueryItem *)queryItem onURL:(NSURL *)sourceURL{
    NSURLComponents *components = [NSURLComponents componentsWithURL:sourceURL resolvingAgainstBaseURL:NO];
    NSArray *array = components.queryItems;
    NSMutableArray *mArray = [NSMutableArray arrayWithArray:array];
    NSInteger i = 0;
    for (i = 0; i<mArray.count; i++) {
        NSURLQueryItem *item = mArray[i];
        if ([item.name isEqualToString:queryItem.name]) {
            [mArray addObject:queryItem];
            [mArray removeObject:item];
            break;
        }
    }
    if (i == mArray.count) {
        [mArray addObject:queryItem];
    }
    components.queryItems = mArray;
    return components.string;
}
- (UIViewController *)getCurrentVC{
    
    UIViewController *result = nil;
    UIWindow * window = [[UIApplication sharedApplication] keyWindow];
    //app默认windowLevel是UIWindowLevelNormal，如果不是，找到UIWindowLevelNormal的
    if (window.windowLevel != UIWindowLevelNormal)
    {
        NSArray *windows = [[UIApplication sharedApplication] windows];
        for(UIWindow * tmpWin in windows)
        {
            if (tmpWin.windowLevel == UIWindowLevelNormal)
            {
                window = tmpWin;
                break;
            }
        }
    }
    id  nextResponder = nil;
    UIViewController *appRootVC=window.rootViewController;
    //    如果是present上来的appRootVC.presentedViewController 不为nil
    if (appRootVC.presentedViewController) {
        nextResponder = appRootVC.presentedViewController;
    }else{
        UIView *frontView = [[window subviews] objectAtIndex:0];
        nextResponder = [frontView nextResponder];
    }
    
    if ([nextResponder isKindOfClass:[UITabBarController class]]){
        UITabBarController * tabbar = (UITabBarController *)nextResponder;
        UINavigationController * nav = (UINavigationController *)tabbar.viewControllers[tabbar.selectedIndex];
        //        UINavigationController * nav = tabbar.selectedViewController ; 上下两种写法都行
        result=nav.childViewControllers.lastObject;
        
    }else if ([nextResponder isKindOfClass:[UINavigationController class]]){
        UIViewController * nav = (UIViewController *)nextResponder;
        result = nav.childViewControllers.lastObject;
    }else{
        result = nextResponder;
    }
    
    return result;
}


-(void)showViewController:(UIViewController *)vc inSecond:(CGFloat)second{
    NSEnumerator *frontToBackWindows = [UIApplication.sharedApplication.windows reverseObjectEnumerator];
    for (UIWindow *window in frontToBackWindows){
        BOOL windowOnMainScreen = window.screen == UIScreen.mainScreen;
        BOOL windowIsVisible = !window.hidden && window.alpha > 0;
        BOOL windowLevelNormal = window.windowLevel == UIWindowLevelNormal;
        
        if(windowOnMainScreen && windowIsVisible && windowLevelNormal){
            
            
            self.currentBGVC = vc;
            
            if (second<=0.0f) {
                [window addSubview:vc.view];
            }else{
                
                vc.view.alpha = 0.0f;
                [window addSubview:vc.view];
                [UIView animateWithDuration:second animations:^{
                    vc.view.alpha=1.0f;
                }];
                
            }
            

            break;
        }
    }
}

-(void)dismissWithAnimation:(CGFloat)second{
    if (self.currentBGVC!=nil) {
        if (second<=0) {
            [self.currentBGVC.view removeFromSuperview];
            self.currentBGVC = nil;
        }else{
            [UIView animateWithDuration:second animations:^{
                self.currentBGVC.view.alpha=0.0f;
            }completion:^(BOOL finished) {
                [self.currentBGVC.view removeFromSuperview];
                self.currentBGVC = nil;
            }];
        }
    }
}

-(void)saveTokenString:(NSString*)token{
    if ([self.tokenString isEqualToString:token]==NO) {
        self.tokenString = token;
        [[NSUserDefaults standardUserDefaults]setObject:token forKey:@"tokenString"];
        [[NSUserDefaults standardUserDefaults]synchronize];
    }
}

- (NSString*)convertToJSONData:(id)infoDict
{
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:infoDict
                                                       options:NSJSONWritingPrettyPrinted // Pass 0 if you don't care about the readability of the generated string
                                                         error:&error];
    
    NSString *jsonString = @"";
    
    if (! jsonData)
    {
        NSLog(@"Got an error: %@", error);
    }else
    {
        jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    
    jsonString = [jsonString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];  //去除掉首尾的空白字符和换行字符
    
    [jsonString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    
    return jsonString;
}

@end
